<template>
  <div>
    <div class="search-box">
      <div class="search-input"><input id="searchInput" type="text" v-model="tagSearchKeyword"></div>
      <ul v-on:mousewheel="load" class="list-group" style="margin-top: 10px;">
        <li class="list-group-item disabled" style="text-align: center;">{{tagSearchKeyword ? '搜索到' + total + '个结果' : '输入标签名称进行搜索'}}</li>
        <TagSearchItem v-for="res in tagSearchResult" :key="res.id" :tagId="res.id" :tagName="res.completeName" :selected="isSelectedTag(res.id)" v-on:addTag="$emit('addTag', {tagId: $event.tagId, tagName: $event.tagName})" v-on:prepareCreateTag="prepareCreateTag($event.tagId, $event.tagName)" v-on:deleteTag="deleteTag($event.tagId, $event.tagName)" v-on:renameTag="renameTag($event.tagId, $event.tagName)"></TagSearchItem>
      </ul>
    </div>
    <div style="margin-top: 20px;">
      <SelectedTag v-for="(tagName, tagId) in selectedTags" v-bind:key="tagId" v-bind:tagId="tagId" v-bind:tagName="tagName" v-on:removeSelectedTag="$emit('removeSelectedTag', $event)"></SelectedTag>
    </div>
    <div class="create-tag-box" style="margin-top: 20px;">
      <span v-if="create.creating">
        <span>{{create.parentTagName}}</span>
        <input type="text" v-model="create.tagName" id="createTagInput">
      </span>
      <button class="btn btn-primary" @click="create.creating ? createTag() : prepareCreateTag(null, null)">{{create.creating ? '创建' : '创建根标签'}}</button>
      <button v-if="create.creating" class="btn btn-primary" @click="create.creating = false">取消</button>
    </div>
    <div style="margin-top: 10px; margin-left: 5px;">
      <span>最近使用的标签：</span>
      <div><span v-for="tag in getRecentTags()" title="tagName" class="tag" @click="$emit('addTag', {tagId: tag.tagId, tagName: tag.tagName})">{{ tag.tagName }}</span></div>
    </div>
    <div :class="{'show': errorMsg}" class="toast align-items-center text-bg-danger border-0" role="alert" aria-live="assertive" aria-atomic="true" style="position: absolute; bottom: -150px; left: 50px;z-index: 10000;">
      <div class="d-flex">
        <div class="toast-body">
          {{errorMsg}}
        </div>
        <button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
      </div>
    </div>
  </div>
</template>

<script>
  import "@/assets/css/classes.css"
  import http from '../../utils/http.js'
  import store from '../../utils/store.js'
  import SelectedTag from './SelectedTag'
  import TagSearchItem from './TagSearchItem'
  export default {
    name: 'TagManager',
    props: ['selectedTags'],
    components: {
      SelectedTag,
      TagSearchItem,
    },
    methods: {
      /**
       * 标签是否已被选中
       * */
      isSelectedTag(tagId) {
        return this.selectedTags.hasOwnProperty(tagId);
      },
      searchTag() {
        let that = this;
        http.get('/tag', {
          pageNum: that.searchPageNum,
          pageSize: that.searchPageSize,
          fuzzyTagName: that.tagSearchKeyword
        }, data => {
          that.total = data.total;
          that.totalPage = Math.ceil(data.total / that.searchPageSize);
          that.tagSearchResult = that.tagSearchResult.concat(data.list)
                                .sort((t1, t2) => t1.completeName == t2.completeName ? 0 : (t1.completeName < t2.completeName ? -1 : 1));
        })
      },
      refreshSearchTag() {
        this.tagSearchResult = [];
        let currentPageNum = this.searchPageNum;
        for (let i = 1; i <= currentPageNum; i++) {
          this.searchPageNum = i;
          this.searchTag();
        }
      },
      prepareCreateTag(parentTagId, parentTagName) {
        this.create.creating = true;
        this.create.parentTagId = parentTagId;
        this.create.parentTagName = parentTagName ? parentTagName + '/' : '/';
        setTimeout(function() {document.getElementById('createTagInput').focus();}, 100)
      },
      createTag() {
        let that = this;
        http.post('/tag', JSON.stringify({parentTagId: this.create.parentTagId, tagName: this.create.tagName}), data => {
          that.create.creating = false;
          if (that.create.parentTagId) {
            that.create.parentTagId = null;
            that.create.parentTagName = null;
          }
          that.create.tagName = null;
          if (that.tagSearchKeyword) {
            that.refreshSearchTag();
          }
        }, res => {
            that.errorMsg = res.errorMsg;
            setTimeout(() => {
              that.errorMsg = null;
            }, 3000);
        })
      },
      deleteTag(tagId, tagName) {
        let that = this;
        http.get('/tag/referNum', {tagId: tagId}, data => {
          let deleteFlag = (data == 0 || confirm("该标签被引用了" + data + "次, 是否确定要删除？"));
          if (deleteFlag) {
            http.delete_request('/tag?tagId=' + tagId, '', data => {
              Object.entries(that.selectedTags).forEach(entry => {
                let [id, name] = entry;
                if (name.startsWith(tagName + '/')) {
                  that.$emit('removeSelectedTag', id);
                }
              })
              that.refreshSearchTag();
            })
          }
        })
      },
      renameTag(tagId, tagName) {
        let that = this;
        while (true) {
          let newTagName = prompt('修改标签[' + tagName + ']，输入新的标签名称', tagName.substring(tagName.lastIndexOf('/') + 1));
          if (newTagName == null) {
            // 点击了取消
            break;
          } else if (newTagName.match(/^[ ]*$/)) {
            alert('名称不能为空');
          } else {
            http.put('/tag/rename', {id: tagId, newTagName: newTagName.trim()}, data => {
              that.refreshSearchTag();
            });
            break;
          }
        }
      },
      load() {
        let tagSearchBox = document.querySelector('.list-group');
        if (Math.ceil(tagSearchBox.clientHeight) + Math.ceil(tagSearchBox.scrollTop) >= tagSearchBox.scrollHeight) {
          if (this.searchPageNum < this.totalPage && this.tagSearchKeyword) {
            this.searchPageNum += 1;
            this.searchTag();
          }
        }
      },
      getRecentTags() {
        return store.recentUsingTagManager.getRecentTags();
      },
      addTag(tag) {
        $emit('addTag', {tagId: tag.tagId, tagName: tag.tagName});
      },
    },
    watch: {
      tagSearchKeyword: {
        handler: function (to, from) {
          this.searchPageNum = 1;
          this.totalPage = 1;
          if (to) {
            this.tagSearchResult = [];
            this.searchTag();
          } else {
            this.tagSearchResult = [];
          }
        },
      }
    },
    data() {
      return {
        searchPageSize: 50,
        searchPageNum: 1,
        totalPage: 1,
        total: 0,
        tagSearchKeyword: '',
        tagSearchResult: [],
        create: {
          parentTagId: null,
          parentTagName: null,
          creating: false,
          tagName: null
        },
        errorMsg: null,
      }
    }
  }
</script>

<style scoped>
  .search-box {

  }
  .search-input {
    margin: 0 auto;
    width: 250px;
  }
  .search-input input {
    width: inherit;
  }
  .search-box .list-group {
    height: 211px;
    overflow-y: scroll;
  }
  .search-box .list-group .list-group-item {
    padding: 5px 16px;
  }
  .search-box .list-group .list-group-item:hover {
    background-color: #c2d8d9;
  }

  .create-tag-box {

  }
  .create-tag-box button {
    margin-left: 10px;
    height: 30px;
    line-height: 30px;
    padding: 0 15px;
  }
</style>
